package com.javagroup.chessonline.client;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JFrame;

import com.javagroup.chessonline.chess.Board;
import com.javagroup.chessonline.chessman.ChessData;
import com.javagroup.chessonline.chessman.Chessman;
import com.javagroup.chessonline.pojo.ChessOnlineRoom;
import com.javagroup.chessonline.view.ChessOnlineView;
import com.javagroup.chessonline.view.CreateRoomForm;
import com.javagroup.chessonline.view.HomePageView;
import com.javagroup.chessonline.view.LobbyView;
import com.javagroup.chessonline.view.RoomView;
import com.thuan.hibernate.Repository;
import com.thuan.hibernate.Utils;

public class Client implements ActionListener, Runnable {

	public static final String HOME_PAGE_VIEW_ID = "home-page-view";
	public static final String LOBBY_VIEW_ID = "lobby-view";
	public static final String ROOM_VIEW_ID = "room-view";
	private static final String CREATE_ROOM_VIEW_ID = "create-room-view";
	
	private JFrame mFrame;

	ClientWorker cw = null;
	Socket client;
	int id = -1;
	Board board = null;
	JButton btnTeamA = null;
	JButton btnTeamB = null;
	JButton btnTest = null;

	// View management
	private Map<String, ChessOnlineView> mViews = new HashMap<>();
	
	// User management
	private HomePageView mHomePageView;
	private LobbyView mLobbyView;
	private RoomView mRoomView;
	private CreateRoomForm mCreateRoomView;

	
	public Board getBoard() {
		return board;
	}

	public void setBoard(Board board) {
		this.board = board;
	}

	Client that = this; // luu tam bien this
	
	public ClientWorker getCw() {
		return cw;
	}

	public void setCw(ClientWorker cw) {
		this.cw = cw;
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Client window = new Client();
					window.mFrame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 * 
	 * @throws IOException
	 */
	public Client() throws IOException {
		initialize();
	}

	/**
	 * Initialize the contents of the frame.
	 * 
	 * @throws IOException
	 */
	private void initialize() throws IOException {
		mFrame = new JFrame();
		mFrame.setTitle("Client");
		mFrame.setBounds(0, 0, 800, 600);
		mFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		mFrame.getContentPane().setLayout(new BorderLayout());

		// code create board

		/*
		 * Board board = new Board(whiteBlock,blackBlock);
		 * 
		 * 
		 * 
		 * frame.getContentPane().add(board,BorderLayout.CENTER);
		 */
		/*// add panel test
		JPanel testPanel = new JPanel();
		testPanel.setPreferredSize(new Dimension(110, 200));
		testPanel.setSize(500, 500);
		testPanel.setLayout(null);

		btnTest = new JButton("CONNECT");
		btnTest.setActionCommand("btnTest");
		btnTest.setBounds(10, 39, 89, 23);
		btnTest.addActionListener(this);

		testPanel.add(btnTest);
		JLabel testLbl = new JLabel();
		testLbl.setPreferredSize(new Dimension(100, 100));
		testLbl.setBounds(10, 11, 86, 14);
		testLbl.setText("Room Information");
		testPanel.add(testLbl);
		frame.getContentPane().add(testPanel, BorderLayout.LINE_START);

		btnTeamA = new JButton("TEAM A");

		btnTeamA.setBounds(10, 79, 89, 23);
		testPanel.add(btnTeamA);

		btnTeamB = new JButton("TEAM B");

		btnTeamB.setBounds(10, 113, 89, 23);
		testPanel.add(btnTeamB);

		JButton btnStartNow = new JButton("START");

		btnStartNow.setBounds(10, 147, 89, 23);
		testPanel.add(btnStartNow);

		// event handler
		// btn Team A
		btnTeamA.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				// cw.send("TeamA");
				cw.sendObject(new ChessData("TeamA"));
			}
		});
		// btn Team B
		btnTeamB.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// cw.send("TeamB");
				cw.sendObject(new ChessData("TeamB"));

			}
		});
		// btn Start
		btnStartNow.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// cw.send("Start now");
				cw.sendObject(new ChessData("Start now"));
				
				 * if(cw.get().equals("Current turn")){ int currentTurn =
				 * Integer.parseInt(cw.get());
				 * System.out.println("turn hien tai la" + currentTurn);
				 * board.getMouseListener().setTurn(currentTurn); }
				 
			}
		});*/
		
		showHomePageView();
		this.login("theturtle232", "Theturtle232");
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		if (e.getActionCommand().equals("btnTest")) {
			new Thread(this).start();
			btnTest.setEnabled(false);
			// System.out.println("dsalkdsa");

		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		try {
			client = new Socket("localhost", 3579);
			if (client.isConnected())
				cw = new ClientWorker(client, this);
			new Thread(cw).start();

		} catch (UnknownHostException ev) {
			// TODO Auto-generated catch block
			ev.printStackTrace();
		} catch (IOException ev) {
			// TODO Auto-generated catch block
			ev.printStackTrace();
		}
	}

	public void loadTeamA(Client client) {
		try {
			board = new Board(client);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		mFrame.getContentPane().add(board, BorderLayout.CENTER);
		mFrame.revalidate();
		id = 0; // team A
		board.getMouseListener().setTeam(id);
		btnTeamB.setEnabled(false);
	}

	public void loadTeamB(Client client) {

		try {
			board = new Board(client);
		} catch (IOException ev) {
			// TODO Auto-generated catch block
			ev.printStackTrace();
		}

		mFrame.getContentPane().add(board, BorderLayout.CENTER);
		mFrame.revalidate();
		id = 1; // team B
		board.getMouseListener().setTeam(id);
		btnTeamA.setEnabled(false);

	}

	public void setCurrentTurn(int turn) {
		board.getMouseListener().setTurn(turn);
	}

	public void refreshBoard(ChessData data) {
		board.setArrayChess(data.getArrayChess());
		board.refreshBoard();
	}

	public void refreshBoard(Chessman[] data) {
		board.setArrayChess(data);
		board.refreshBoard();
	}

	// User Management
	//
	public void login(String username, String password) {
		if(Repository.login(username, password) == true) {
			Utils.saveUserSession(username);
			// Go to lobby panel
			showLobbyView();
		}
		else {
			// Show error
			this.mHomePageView.getLoginForm().setInvalidUserError();
		}
	}
	
	public void register(String username, String password, String name) {
		if(Repository.addUser(username, password, name) == -1) {
			this.mHomePageView.getRegisterForm().setInvalidUserError();
		}
		else {
			// Go to room panel
			Utils.saveUserSession(username);
			
			showLobbyView();
		}
		
	}
	
	// View Management
	//
	private void addViewComponent(String id, ChessOnlineView component, String layout) {
		this.mFrame.getContentPane().add(component, layout);
		this.addView(id, component);
	}
	private void addViewComponent(String id, ChessOnlineView component, LayoutManager layout) {
		this.mFrame.getContentPane().setLayout(layout);
		this.mFrame.getContentPane().add(component);
		this.addView(id, component);
	}
	
	private void addView(String id, ChessOnlineView view) {
		if(!this.mViews.containsKey(id)) {
			this.mViews.put(id, view);
		}
	}
	
	private void removeView(String id, ChessOnlineView view) {
		this.mViews.remove(id);
		this.mFrame.remove(view);
		view = null;
	}
	
	public void showView(String id) {
		for(ChessOnlineView view : this.mViews.values()) {
			view.setVisible(false);
			view.onHide();
		}
		
		this.mViews.get(id).onShow();
		this.mViews.get(id).setVisible(true);
		this.mFrame.invalidate();
	}
	
	public void showLobbyView() {
		if(mLobbyView != null) {
			removeView(Client.LOBBY_VIEW_ID, mLobbyView);
		}
		
		mLobbyView = new LobbyView(this);
		this.addViewComponent(Client.LOBBY_VIEW_ID, mLobbyView, BorderLayout.CENTER);
		
		mLobbyView.showRoom();
		
		this.showView(LOBBY_VIEW_ID);
	}

	public void showRoomView(ChessOnlineRoom room) {
		if(mRoomView != null) {
			removeView(Client.ROOM_VIEW_ID, mRoomView);
		}
		mRoomView = new RoomView(this, room);
		this.addViewComponent(Client.ROOM_VIEW_ID, mRoomView, BorderLayout.CENTER);
		
		this.showView(ROOM_VIEW_ID);
	}


	public void showHomePageView() {
		// Clear the SESSION
		Utils.removeUserSession();
		
		if(mHomePageView != null) {
			removeView(Client.HOME_PAGE_VIEW_ID, mHomePageView);
		}
		
		mHomePageView = new HomePageView(this);
		this.addViewComponent(Client.HOME_PAGE_VIEW_ID, mHomePageView, BorderLayout.CENTER);
		this.showView(Client.HOME_PAGE_VIEW_ID);
		
	}
	
	public void startGame(ChessOnlineRoom mRoom) {
		// TODO: Call to server to start the game. Server then broadcast the message to 2 player,
		// client then load the board and start the game
	}

	public void createNewRoom(String roomName, int score) {
		// TODO: Call to server to create the room and then switch to room view
		
		// TODO: Check if we are in the League Mode
		// if true, we need to save the current League ID to the room before we
		// submit to create the room on server
		if(Utils.isLeagueMode()) {
			int leagueId = Utils.getLeagueId();
		}
		
				
	}

	public void showCreateRoomView() {
		if(this.mCreateRoomView != null) {
			this.removeView(CREATE_ROOM_VIEW_ID, mCreateRoomView);
		}
		
		this.mCreateRoomView = new CreateRoomForm(this);
		
		this.addViewComponent(CREATE_ROOM_VIEW_ID, this.mCreateRoomView, BorderLayout.CENTER);
		this.showView(CREATE_ROOM_VIEW_ID);
	}

}
